//    Copyright (C) Kherty.  All rights reserved.
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Windows;
using System.Windows.Media;
namespace OpenLS.Chart.UI
{
    class LineSmoother
    {
        public LineSmoother(PointCollection points)
        {
            this.points = points;
        }
        private readonly PointCollection points;

        private double k = 1;
        public PolyBezierSegment GetBezierSegment()
        {
            Contract.Assert(points.Count >= 3);
            {
                var segment = new PolyBezierSegment();
                for (int i = 0; i <= points.Count - 2; i++)
                {
                    Point a, b, c, d;
                    b = points[i];
                    c = points[i + 1];
                    if (i == 0)
                    {
                        a = b + (b - c);
                    }
                    else
                    {
                        a = points[i - 1];
                    }
                    if (i == points.Count - 2)
                    {
                        d = c + (c - b);
                    }
                    else
                        d = points[i + 2];
                    Point p1, p2, unused;
                    GetControlPoints(a, b, c, out unused, out p1);
                    GetControlPoints(b, c, d,  out p2, out unused);
                    segment.Points.Add(p1);
                    segment.Points.Add(p2);
                    segment.Points.Add(c);
                }
                return segment;
            }
        }
        void GetControlPoints(Point a, Point b, Point c, out Point before, out Point after)
        {
            Vector ab = b - a;
            Vector bc = c - b;
            Point mid1 = a + (ab) / 2;
            Point mid2 = b + (bc) / 2;
            double ratio = ab.Length / (ab.Length + bc.Length);
            Point mid = mid1 + (mid2 - mid1) * ratio;
            before = mid1 + (b - mid);
            after = mid2 + (b - mid);

        }


        internal PathSegment GetSegment()
        {
            if (points.Count <= 2)
                return new PolyLineSegment(points, true)
                    ;
            return GetBezierSegment();
        }
    }
}
